import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
import {CommonTool} from '../common/common.tool';
import {HTTP_URLS} from '../config/app-http.url';
import {LoginDto, Node} from './basic.model';
import {environment} from '../../environments/environment';
import {CommonHttp} from '../common/common.http';
import {Router} from '@angular/router';
import {DictService} from '../common/service/dict.service';

@Injectable({
  providedIn: 'root'
})
export class BasicService {

  constructor(private http: HttpClient,
              public commonHttp: CommonHttp,
              private dictService: DictService,
              private router: Router) {

  }

  /**
   * 获取刷新token
   */
  public getRefreshToken(isRefresh?): LoginDto {
    const json = CommonTool.getCookie(environment.tokenKey);
    if (json) {
      const loginDto: LoginDto = new LoginDto(JSON.parse(json));
      if (!isRefresh) {
        const date = CommonTool.turnDate(loginDto.updateTime);
        if ((date.getTime() + loginDto.validTime) > new Date().getTime()) {
          return loginDto;
        }
      }
      const url = CommonTool.analysisUrl(HTTP_URLS.updateMyAppToken, {refreshToken: loginDto.refreshToken});
      const res = this.commonHttp.put(url, {});
      if (res.isSuccess) {
        const data = JSON.parse(res.data);
        CommonTool.setCookie(environment.tokenKey, JSON.stringify(data));
        return new LoginDto(data);
      } else {
        CommonTool.deleteCookie(environment.tokenKey);
        localStorage.clear();
        this.router.navigate(['/login']);
      }
    }
    return null;
  }

  /**
   * 退出登录
   */
  public logOut() {
    const token = CommonTool.getCookie(environment.tokenKey);
    if (CommonTool.notNull(token)) {
      this.http.delete(HTTP_URLS.deleteMyAppToken).subscribe(res => {
        CommonTool.deleteCookie(environment.tokenKey);
        localStorage.clear();
        this.router.navigate(['/login']);
      }, () => {
        CommonTool.deleteCookie(environment.tokenKey);
        localStorage.clear();
        this.router.navigate(['/login']);
      });
      return;
    } else {
      CommonTool.deleteCookie(environment.tokenKey);
      localStorage.clear();
      this.router.navigate(['/login']);
    }
  }

  /**
   *  获取token
   */
  public getToken(code, accessToken) {
    const url = CommonTool.analysisParam(HTTP_URLS.getMyAppToken, {code, accessToken: accessToken});
    return this.http.get(url);
  }

  /***
   * 获取应用的菜单信息集合
   */
  public getMyAppMenuList(): Observable<any> {
    return this.http.get(HTTP_URLS.getMyAppMenuList);
  }

  /**
   * 菜单处理
   */
  public menuHandle(array, authorityCodes) {
    array = this.getMenus(array, authorityCodes);
    const nodes = [];
    for (const arr of array) {
      nodes.push({
        node: arr.node,
        parentNode: arr.parentNode,
        seq: arr.seq,
        title: arr.name,
        icon: arr.icon,
        url: arr.url,
        open: false,
        selected: false,
        disabled: false
      });
    }
    return this.getTrees('root', nodes);
  }

  /**
   * 获取菜单
   */
  private getMenus(menus: Array<any>, authorityCodes: Array<any>) {
    const result = [];
    for (const authorityCode of authorityCodes) {
      for (const menu of menus) {
        if (authorityCode === menu.code) {
          result.push(menu);
        }
      }
    }
    return result;
  }

  /**
   * 获取节点树
   */
  public getTrees(parentNode: string, nodes: Array<Node>) {
    const trees: Array<Node> = [];
    const array = this.getChildrenNodes(parentNode, nodes);
    for (const arr of array) {
      const children = this.getTrees(arr.node, nodes);
      if (children != null && children.length > 0) {
        arr.children = children;
        arr.isLeaf = false;
      } else {
        arr.isLeaf = true;
      }
      trees.push(arr);
    }
    trees.sort((a, b) => {
      if (a.seq != null && b.seq != null) {
        return a.seq - b.seq;
      }
      return 1;
    });
    return trees;
  }

  /**
   * 获取当前节点的子节点集合
   */
  private getChildrenNodes(parentNode, nodes: Array<Node>) {
    const array: Array<Node> = [];
    for (const node of nodes) {
      if (parentNode === node.parentNode) {
        array.push(node);
      }
    }
    return array;
  }

  /**
   * 跳转登录
   */
  public jumpLogin() {
    const state = Math.ceil(Math.random() * 100000);
    const redirectUri = escape(location.origin + environment.config.redirectPath);
    location.href = environment.config.loginUrl + '&redirectUri=' + redirectUri + '&state=' + state;
    localStorage.setItem('state', state + '');
  }

  /**
   * 提交
   */
  public initLogin(res, authorityCodes, fun): void {
    // token存储
    CommonTool.setCookie(environment.tokenKey, JSON.stringify(new LoginDto(res)));
    // 权限去重
    authorityCodes = authorityCodes.filter((item, index) => {
      return authorityCodes.indexOf(item, 0) === index;
    });
    // 权限存储
    localStorage.setItem(environment.authorityKey, JSON.stringify(authorityCodes));
    // 菜单查询
    this.getMyAppMenuList().subscribe(menus => {
      // 菜单处理
      const menuList = this.menuHandle(menus, authorityCodes);
      if (menuList) {
        // 菜单存储
        localStorage.setItem(environment.menuKey, JSON.stringify(menuList));
      }
      // 字典查询
      this.dictService.getDictMap().subscribe(() => {
        if (fun) {
          fun();
        }
      });
    });
  }
}
